package com.lidy.tankbattle.tankgame2.tank;

import com.lidy.tankbattle.tankgame2.constant.BulletPriorities;
import com.lidy.tankbattle.tankgame2.constant.TankPriorities;
import com.lidy.tankbattle.tankgame2.bullet.Bullet;
import com.lidy.tankbattle.tankutils.ThreadUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalTime;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author lidy
 * @version V2.0
 * @classname Tank
 * @description 坦克父类
 * @date 2022/5/28 13:36
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Tank {
    /**
     * 坦克编号
    **/
    private int number;

    /**
     * X坐标
     **/
    private int x;

    /**
     * Y坐标
     **/
    private int y;

    /**
     * 坦克宽度
     **/
    private int width;

    /**
     * 坦克高度
     **/
    private int height;

    /**
     * 速度
    **/
    private int speed;

    /**
     * 坦克类型
    **/
    private int type;

    /**
     * 0-上，1-下，2-左，3-右
     **/
    private int direction;

    /**
     * 坦克血量
    **/
    private int bloodVolume;

    /**
     * 坦克是否存活
     **/
    private Boolean live = true;

    /**
     * 创建时间
     **/
    private LocalTime createdTime;

    /**
     * 是否无敌
     **/
    private Boolean invincible;

    /**
     * 坦克子弹集合
     **/
    private ConcurrentHashMap<Bullet, Integer> bullets = new ConcurrentHashMap<>(30);

    /**
     * 坦克不同方向图片地址
    **/
    private String upImageAddress;
    private String downImageAddress;
    private String leftImageAddress;
    private String rightImageAddress;


    public Tank(int x, int y, int width, int height, int type, int direction, int number, int bloodVolume, LocalTime createdTime, Boolean invincible) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
        this.type = type;
        this.direction = direction;
        this.number = number;
        this.bloodVolume = bloodVolume;
        this.speed = type == TankPriorities.MY_TANK_TYPE ? TankPriorities.MY_TANK_INIT_SPEED : TankPriorities.ENEMY_TANK_INIT_SPEED;
        this.createdTime = createdTime;
        this.invincible = invincible;
        initImages(type);
    }

    /**
     * @author: lidy
     * @description: 初始化坦克图片地址
     * @date: 2022/6/2 16:32
     */
    public void initImages(int type) {
        String path = "/images";
        if (type == TankPriorities.MY_TANK_TYPE) {
            path += "/player1";
        } else {
            path += "/enemy";
        }
        upImageAddress = path + "/tankU.gif";
        downImageAddress = path + "/tankD.gif";
        leftImageAddress = path + "/tankL.gif";
        rightImageAddress = path + "/tankR.gif";
    }

    /**
     * @author: lidy
     * @description: 发射一颗子弹
     * @date: 2022/6/1 19:13
     */
    public void shot() {
        int bulletX;
        int bulletY;
        int offset = (width - BulletPriorities.BULLET_WIDTH) / 2;
        int toTankGunBattleLength = 10;
        switch (this.getDirection()) {
            case TankPriorities.DIRECTION_DOWN -> {
                bulletX = this.getX() + offset;
                bulletY = this.getY() + height + toTankGunBattleLength;
            }
            case TankPriorities.DIRECTION_LEFT -> {
                bulletX = this.getX() - BulletPriorities.BULLET_LENGTH - toTankGunBattleLength;
                bulletY = this.getY() + offset;
            }
            case TankPriorities.DIRECTION_RIGHT -> {
                bulletX = this.getX() + height + toTankGunBattleLength;
                bulletY = this.getY() + offset;
            }
            default -> {
                bulletX = this.getX() + offset;
                bulletY = this.getY() - BulletPriorities.BULLET_LENGTH - toTankGunBattleLength;
            }
        }
        Bullet bullet = new Bullet(bulletX, bulletY, this.getDirection(), this.getType(), this.getNumber());
        // 将子弹添加到坦克子弹集合中
        bullets.put(bullet, this.number);
        //启动一个线程不断修改子弹的坐标
        ThreadUtil.threadPoolExecutor.execute(bullet);
    }

    public void moveRightSpeed() {
        x += speed;
    }

    public void moveLeftSpeed() {
        x -= speed;
    }

    public void moveDownSpeed() {
        y += speed;
    }

    public void moveUpSpeed() {
        y -= speed;
    }

    public void moveRight(int value) {
        x += value;
    }

    public void moveLeft(int value) {
        x -= value;
    }

    public void moveDown(int value) {
        y += value;
    }

    public void moveUp(int value) {
        y -= value;
    }

    public void reduceBlood(int value) {
        bloodVolume -= value;
        if (bloodVolume <= 0) {
            live = false;
        }
    }
}
